package cn.janescott.inner.space.webapp.adapter;

import io.jsonwebtoken.lang.Assert;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.jasypt.util.password.PasswordEncryptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 密码处理器
 *
 * @author scott
 * @date 2018/7/31
 */
public class MyPasswordAdapter implements CredentialsMatcher {
    private Logger logger = LoggerFactory.getLogger(getClass());

    private PasswordEncryptor encryptor;

    public MyPasswordAdapter setEncryptor(PasswordEncryptor encryptor) {
        this.encryptor = encryptor;
        return this;
    }

    /**
     * 适配shiro 密码校验
     *
     * @param token 登录信息
     * @param info  数据库信息
     * @return 校验结果
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        try {
            Assert.notNull(token);
            Assert.notNull(info);
            String plain = null;
            String encrypted = null;
            if (null != token.getCredentials() && token.getCredentials() instanceof char[]) {
                plain = new String((char[]) token.getCredentials());
            }
            if (null != info.getCredentials() && info.getCredentials() instanceof char[]) {
                encrypted = new String((char[]) info.getCredentials());
            }
            if (!checkPassword(plain, encrypted)) {
                throw new IncorrectCredentialsException();
            }
            return true;
        } catch (Exception ex) {
            if (ex instanceof IncorrectCredentialsException) {
                throw ex;
            } else if (ex instanceof IllegalArgumentException) {
                logger.error(ex.getMessage(), ex);
                return false;
            }
            logger.error(ex.getMessage(), ex);
            throw new AuthenticationException();
        }
    }

    /**
     * 密码加密
     *
     * @param origin 明文
     * @return 密文
     */
    public String encryptPassword(final String origin) {
        return encryptor.encryptPassword(origin);
    }

    /**
     * 密码匹配
     *
     * @param plainPassword     原文
     * @param encryptedPassword 密文
     * @return 结果
     */
    public boolean checkPassword(String plainPassword, String encryptedPassword) {
        return encryptor.checkPassword(plainPassword, encryptedPassword);
    }
}
